package com.xiaoniu.forum.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaoniu.forum.common.constant.ForumConstant;
import com.xiaoniu.forum.common.event.ForumEvent;
import com.xiaoniu.forum.common.utils.CommonQueryVo;
import com.xiaoniu.forum.common.utils.QueryWrapperUtils;
import com.xiaoniu.forum.config.RabbitConfig;
import com.xiaoniu.forum.dao.*;
import com.xiaoniu.forum.entity.*;

import com.xiaoniu.forum.entity.vo.*;
import com.xiaoniu.forum.form.TopicSaveOrUpdateForm;
import com.xiaoniu.forum.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoniu.forum.common.utils.PageUtils;
import com.xiaoniu.forum.common.utils.Query;

import org.springframework.util.StringUtils;


@Service("communityTopicService")
@Slf4j
public class CommunityTopicServiceImpl extends ServiceImpl<CommunityTopicDao, CommunityTopicEntity> implements CommunityTopicService {

    @Autowired
    private CommunityTopicStatusDao communityTopicStatusDao;
    @Autowired
    private CommunityCategoryDao communityCategoryDao;
    @Autowired
    private CommunityDao communityDao;
    @Autowired
    private CommunityTopicCategoryDao communityTopicCategoryDao;
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private MemberNospeakDao memberNospeakDao;
    @Autowired
    private CommunityTopicCommentDao communityTopicCommentDao;
    @Autowired
    private MemberMessageService messageService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private TopicSearchService topicSearchService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CommunityTopicEntity> page = this.page(
                new Query<CommunityTopicEntity>().getPage(params),
                new QueryWrapper<CommunityTopicEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params,QueryWrapper<CommunityTopicEntity> wrapper) {
        IPage<CommunityTopicEntity> page = this.page(
                new Query<CommunityTopicEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(CommonQueryVo queryVo) {
        QueryWrapper<CommunityTopicEntity> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(queryVo.getAnd()) || !StringUtils.isEmpty(queryVo.getOr())) {
            wrapper = QueryWrapperUtils.createQueryWrapper(queryVo, CommunityTopicEntity.class);
        }

        IPage<CommunityTopicEntity> page = this.page(new Query<CommunityTopicEntity>().getPage(queryVo.getPageParams()),wrapper);

        //封装VO
        List<CommunityTopicEntity> communityTopicEntityList = page.getRecords();

        List<CommunityTopicListVo> list = new ArrayList<>();

        for (CommunityTopicEntity communityTopicEntity : communityTopicEntityList) {
            CommunityTopicListVo communityTopicListVo = new CommunityTopicListVo();
            //复制对象
            BeanUtils.copyProperties(communityTopicEntity,communityTopicListVo);
            //封装options:话题所在路径===> 社区分类/板块分类/话题分类
            CommunityCategoryEntity communityCategoryEntity = communityCategoryDao.selectById(communityTopicEntity.getCommunityCategoryId());
            if (communityCategoryEntity !=null)
                communityTopicListVo.getOptions().add(new OptionsVo(communityCategoryEntity.getId(),communityCategoryEntity.getName()));

            CommunityEntity communityEntity = communityDao.selectById(communityTopicEntity.getCommunityId());
            if (communityEntity !=null)
            communityTopicListVo.getOptions().add(new OptionsVo(communityEntity.getId(),communityEntity.getName()));

            CommunityTopicCategoryEntity communityTopicCategoryEntity = communityTopicCategoryDao.selectById(communityTopicEntity.getTopicCategoryId());
            if (communityTopicCategoryEntity !=null)
                communityTopicListVo.getOptions().add(new OptionsVo(communityTopicCategoryEntity.getId(),communityTopicCategoryEntity.getName()));

            //封装用户姓名
            MemberEntity memberEntity = memberDao.selectById(communityTopicEntity.getUserId());
            if (memberEntity != null)
                communityTopicListVo.setUserName(memberEntity.getUsername()+"::"+memberEntity.getNickname());

            QueryWrapper<CommunityTopicStatusEntity> wr = new QueryWrapper<>();
            wr.eq("threads_id",communityTopicEntity.getId());
            CommunityTopicStatusEntity communityTopicStatusEntity = communityTopicStatusDao.selectOne(wr);
            communityTopicListVo.setTopicStatus(communityTopicStatusEntity);

            //添加到list
            list.add(communityTopicListVo);
        }
        //封装Page对象并返回
        Page<CommunityTopicListVo> resultPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        resultPage.setRecords(list);
        return new PageUtils(resultPage);
    }

    @Override
    public void save(TopicSaveOrUpdateForm form) {
        CommunityTopicEntity communityTopicEntity = new CommunityTopicEntity();
        BeanUtils.copyProperties(form,communityTopicEntity);

        //如果该话题状态为公告 则将话题类型修改为公告或置顶话题 否则为普通话题
        if (form.getNotice().equals("1")){
            communityTopicEntity.setType("2");
        }else{
            communityTopicEntity.setType("1");
        }

        baseMapper.insert(communityTopicEntity);

        CommunityTopicStatusEntity topicStatusEntity = new CommunityTopicStatusEntity();
        topicStatusEntity.setThreadsId(communityTopicEntity.getId());
        topicStatusEntity.setNotice(form.getNotice());
        communityTopicStatusDao.insert(topicStatusEntity);
    }


    @Override
    public void updateById(TopicSaveOrUpdateForm form) {
        CommunityTopicEntity communityTopicEntity = new CommunityTopicEntity();
        BeanUtils.copyProperties(form,communityTopicEntity);

        //如果该话题状态为公告 则将话题类型修改为公告或置顶话题 否则为普通话题
        if (form.getNotice().equals("1")){
            communityTopicEntity.setType("2");
        }else{
            communityTopicEntity.setType("1");
        }

        baseMapper.updateById(communityTopicEntity);

        CommunityTopicStatusEntity communityTopicStatusEntity = new CommunityTopicStatusEntity();
        BeanUtils.copyProperties(form,communityTopicStatusEntity);
        communityTopicStatusEntity.setThreadsId(form.getId());

        //如果设置为公告 即notice=1时  则清空其他状态
        if (communityTopicStatusEntity.getNotice().equals("1")){
            communityTopicStatusEntity.setElite("0");
            communityTopicStatusEntity.setHot("0");
            communityTopicStatusEntity.setTop("0");
            communityTopicStatusEntity.setNewly("0");
        }
        communityTopicStatusDao.updateById(communityTopicStatusEntity);

        //更新话题时，将话题id发送到消息队列，交给消费者处理
        List<Object> ids = new ArrayList<>();
        ids.add(communityTopicEntity.getId());
        rabbitTemplate.convertAndSend(null, RabbitConfig.UPDATE_TOPIC_QUEUE,JSON.toJSONString(ids));
    }

    @Override
    public ComunityTopiclUpdateInfoVo getById(String id) {
        CommunityTopicEntity communityTopicEntity = baseMapper.selectById(id);

        ComunityTopiclUpdateInfoVo comunityTopiclUpdateInfoVo = new ComunityTopiclUpdateInfoVo();

        BeanUtils.copyProperties(communityTopicEntity,comunityTopiclUpdateInfoVo);

        QueryWrapper<CommunityTopicStatusEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("threads_id",id);
        CommunityTopicStatusEntity communityTopicStatusEntity = communityTopicStatusDao.selectOne(wrapper);

        comunityTopiclUpdateInfoVo.setNotice(communityTopicStatusEntity.getNotice());

        return comunityTopiclUpdateInfoVo;
    }

    @Override
    public CommunityTopicStatusEntity getTopicStatusBycommunityTopicId(String communityTopicId) {
        QueryWrapper<CommunityTopicStatusEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("threads_id",communityTopicId);

        return communityTopicStatusDao.selectOne(wrapper);
    }

    @Override
    public void updateTopicStatus(CommunityTopicStatusEntity communityTopicStatusEntity) {

        //修改话题状态的同时,也修改话题的状态
        CommunityTopicEntity communityTopicEntity = baseMapper.selectById(communityTopicStatusEntity.getThreadsId());

        if (communityTopicStatusEntity.getTop().equals("1")){
            communityTopicEntity.setType("2");
        }else{
            communityTopicEntity.setType("1");
        }

        baseMapper.updateById(communityTopicEntity);
        communityTopicStatusDao.updateById(communityTopicStatusEntity);
    }

    @Override
    public boolean updateTopicBatchById(List<CommunityTopicEntity> topicList) {
        boolean b = this.updateBatchById(topicList, topicList.size());

        //更新话题时，将话题id发送到消息队列，交给消费者处理
        List<Object> ids = new ArrayList<>();
        topicList.forEach((topic)->ids.add(topic.getId()));
        rabbitTemplate.convertAndSend(null, RabbitConfig.UPDATE_TOPIC_QUEUE,JSON.toJSONString(ids));
        return b;
    }

    @Override
    public PageUtils getListForPass(Map<String, Object> params) {

        QueryWrapper<CommunityTopicEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("pass","2");
        wrapper.eq("status","1");

        PageUtils page = this.queryPage(params,wrapper);

        List communityTopicList = page.getList();

        List<PassListVo> list = new ArrayList<>();

        //将数据列表封装为passListVo
        for (Object obj : communityTopicList) {
            CommunityTopicEntity communityTopicEntity = (CommunityTopicEntity) obj;
            PassListVo passListVo = new PassListVo();

            //封装用户信息
            MemberEntity memberEntity = memberDao.selectById(communityTopicEntity.getUserId());
            if (memberEntity != null) {
                passListVo.setUserName(memberEntity.getUsername() + "::" + memberEntity.getNickname());
                passListVo.setMemberStatus(memberEntity.getStatus());
                QueryWrapper<MemberNospeakEntity> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("member_id",memberEntity.getId());
                MemberNospeakEntity memberNospeakEntity = memberNospeakDao.selectOne(queryWrapper);
                if (memberNospeakEntity != null){
                    passListVo.setNospeak("1");
                }
            }

            //封装其他
            passListVo.setId(communityTopicEntity.getId());
            passListVo.setMemberId(communityTopicEntity.getUserId());
            passListVo.setContent(communityTopicEntity.getThreadsText());
            passListVo.setCreateTime(communityTopicEntity.getCreateTime());


            list.add(passListVo);
        }

        page.setList(list);

        return page;
    }

    @Override
    public void passed(String communityTopicId) {
        CommunityTopicEntity topicEntity = baseMapper.selectById(communityTopicId);

        topicEntity.setPass("1");

        baseMapper.updateById(topicEntity);

        //审核通过，将数据保存到ES
        topicSearchService.save(topicEntity);

        ForumEvent forumEvent = new ForumEvent();
        forumEvent
                .setTriggerId(ForumConstant.SYSTEM_ID+"")  //事件触发者（发送人）
                .setTargetId(topicEntity.getUserId())  //事件目标者（接受者）
                .setAction(ForumConstant.APPROVED_ACTION)  //审核通过
                .setData(ForumConstant.KEYNAME_ENTITY_TYPE,ForumConstant.TOPIC_ENTITY_TYPE) //其他数据
                .setData(ForumConstant.KEYNAME_ENTITY_ID,communityTopicId); //其他数据
        messageService.sendEvent(forumEvent);
    }

    @Override
    public void passedFailed(String communityTopicId,String message) {
        CommunityTopicEntity topicEntity = baseMapper.selectById(communityTopicId);
        topicEntity.setPass("0");
        baseMapper.updateById(topicEntity);
        ForumEvent forumEvent = new ForumEvent();
        forumEvent
                .setTriggerId(ForumConstant.SYSTEM_ID+"")  //事件触发者（发送人）
                .setTargetId(topicEntity.getUserId())  //事件目标者（接受者）
                .setAction(ForumConstant.NOT_APPROVED_ACTION)  //审核未通过
                .setData(ForumConstant.KEYNAME_ENTITY_TYPE,ForumConstant.TOPIC_ENTITY_TYPE) //其他数据
                .setData(ForumConstant.KEYNAME_ENTITY_ID,communityTopicId)
                .setData(ForumConstant.KEYNAME_RESON,message);//其他数据
        messageService.sendEvent(forumEvent);
    }

    @Override
    public String getContentById(String id) {
        QueryWrapper<CommunityTopicEntity> wrapper = new QueryWrapper<>();
        wrapper
                .select("threads_text","title")
                .eq("id",id);

        CommunityTopicEntity communityTopicEntity = baseMapper.selectOne(wrapper);
        return "<h1 style='color:grey'>" + communityTopicEntity.getTitle() + "</h1> <hr/>" + communityTopicEntity.getThreadsText();
    }


    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        baseMapper.deleteBatchIds(idList);
        communityTopicStatusDao.deleteBatchIds(idList);

        return true;
    }

    @Override
    public List<AppCommunityTopTopicVo> getTopicTops(String id){
        return baseMapper.getTopicTops(id);
    }
}
